<?php
/**
 * PHP设计模式数据对象映射模式
 * 1.数据对象映射模式,是将对象和数据存储映射起来,对一个对象的 操作会映射为对数据存储的操作
 * 2.在代码中实现数据对象映射模式,我们将实现一个ORM类,将复杂的SQL语句映射成对象属性的操作
 * 3.结合使用数据对象映射模式,工厂模式,注册模式
 */
namespace core\model;

use core\database\driver\MySQLi;

class User
{
	/**
	 * @var MySQLi
	 */
	private $db;
	/**
	 * @var int
	 */
	private $id;
	private $data;

	/**
	 * 构造方法
	 */
	public function __construct()
	{
		if (is_null($this->db)) {
			$this->db = new MySQLi();
			$this->db->connect(
				'127.0.0.1',
				'root',
				'root',
				'qy.wzp.cn'
			);
		}
	}

	public function find(int $id)
	{
		$this->id = $id;
		$res = $this->db->query("select * from user where id = {$this->id} limit 1");
		$data = $res->fetch_assoc();
		if ($data) {
			foreach ( $data as $field => $value ) {
				$this->data[$field] = $value;
			}
		}
		return $this;
	}

	public function save(array $data)
	{
		$array = [];
		foreach ( $data as $field => $value ) {
			if (is_numeric($value)) {
				$array[] = implode(' = ', [$field, $value]);
			} else {
				$array[] = implode(' = ', [$field, sprintf('"%s"', $value)]);
			}
		}

		$sql = "update user set ". implode(', ', $array) ." where id = {$this->id}";

		$result = $this->db->query($sql);
		if (!$result) {
			$message  = "Invalid query: error \n";
    		$message .= 'Whole query: ' . $sql;
			throw new \Exception($message, 1);
		}

		return $result;
	}

	/**
	 * 析构方法: 调用完后，会被销毁
	 */
	public function __destruct()
	{
		//$field = "user_name = '{$this->user_name}', phone = '{$this->phone}'";
		//$this->db->query("update user set {$field} where id = {$this->id}");
	}

	public function __set($key, $value)
	{
		$this->data[$key] = $value;
	}

	public function __get($name)
	{
		if (isset($this->data[$name])) {
			return $this->data[$name];
		}
		return null;
	}

	/**
	 * @param $method
	 * @param $args
	 * @return mixed
	 * @throws \Exception
	 * @author sweeterstar <2021/4/24>
	 */
	static public function __callStatic($method, $args)
	{
		list($front, $method) = explode('_', $method);

		if (!in_array($method, get_class_methods(__CLASS__))) {
            throw new \Exception("method not exists:" . $method);
        }

		return call_user_func_array([self::class, $method], $args);
	}
}